import java.util.Arrays;

public class 你可以安排的最多任务数目 {

    public static int[] tasks; // 任务全局变量
    public static int[] workers; // 工人全局变量
    public static int MAXN = 50001; // 最大值
    public static int[] deque = new int[MAXN]; // 双端队列存储任务下标
    public static int h,t; // 头尾指针
    public static int maxTaskAssign(int[] ts, int[] ws, int pills, int strength) {
        // 全局变量的初始化
        tasks = ts;
        workers = ws;
        // 进行排序, 方便进行贪心操作
        Arrays.sort(tasks);
        Arrays.sort(workers);
        int l = 0;
        int ans = 0; // 任务的最大数量
        int tsize = tasks.length;
        int wsize = workers.length;
        int r = Math.min(tsize, wsize);
        // 二分答案法
        while (l <= r) {
            int mid = (l + r) / 2; // 你需要做的任务数量是否能完成
            if (f(0,mid - 1,wsize - mid,wsize - 1,pills,strength)) {
                // 如果此时能做成任务, 就继续加, 此时的参数是 任务的下标, 工人的下标, 任务从小开始取, 工人由大开始取
                ans = mid;
                l = mid + 1;
            } else {
                r = mid - 1;
            }
        }
        return ans;
    }

    private static boolean f(int tl, int tr, int wl, int wr, int pills, int strength) {
        h = t = 0;
        int cnt = 0; // 实际嗑药数
        // 从小到大遍历所有的工人
        for (int i = wl; i <= wr; i++) {
            // 将工人所有能做的任务全部添加到双端队列中
            while (tl <= tr && workers[i] >= tasks[tl]) {
                deque[t++] = tl++;
            }
            // 如果队列不为空, 工人做最小的任务
            if (h < t && workers[i] >= tasks[deque[h]]) {
                h++;
            } else {
                // 工人没有能做的任务, 选择吃药提升自己
                // 将嗑药后能做的任务全部都添加到队列中
                while (tl <= tr && workers[i] + strength >= tasks[tl]) {
                    deque[t++] = tl++;
                }
                // 队列中有元素, 选择最大的任务做掉
                if (h < t) {
                    cnt++;
                    t--;
                } else {
                    // 没有元素, 说明嗑药以后也不能做最小的任务, 那就不可能完成 ans 个任务, 返回 false
                    return false;
                }
            }
         }
        // 返回嗑药是不是多磕了, 多磕了肯定是失败, <= 说明刚刚好或者药还有剩余
        return cnt <= pills;
    }


}
